/*
 * Copyright (c) 2017, Quancheng-ec.com All right reserved. This software is the
 * confidential and proprietary information of Quancheng-ec.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Quancheng-ec.com.
 */
package com.sinosoft.book.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * @author shimingliu 2017年2月10日 上午12:23:52
 * @version DruidDBConfig.java, v 0.0.1 2017年2月10日 上午12:23:52 shimingliu
 */
@Configuration
public class DruidDBConfig {

    private static final Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);

    @Value("${spring.datasource.url}")
    private String              dbUrl;

    @Value("${spring.datasource.username}")
    private String              username;

    @Value("${spring.datasource.password}")
    private String              password;

    @Value("${spring.datasource.driverClassName}")
    private String              driverClassName;

    @Value("${spring.datasource.initialSize}")
    private int                 initialSize;

    @Value("${spring.datasource.minIdle}")
    private int                 minIdle;

    @Value("${spring.datasource.maxActive}")
    private int                 maxActive;

    @Value("${spring.datasource.maxWait}")
    private int                 maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int                 timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int                 minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String              validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean             testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private boolean             testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private boolean             testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean             poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int                 maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.filters}")
    private String              filters;

    @Value("{spring.datasource.connectionProperties}")
    private String              connectionProperties;

    @Bean // 声明其为Bean实例
    @Primary // 在同样的DataSource中，首先使用被标注的DataSource
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();

        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);

        // configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter", e);
        }
        datasource.setConnectionProperties(connectionProperties);

        return datasource;
    }
}
